/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package it.polimi.deib.se2.meteocal.business.control;

import it.polimi.deib.se2.meteocal.business.boundary.LocationManager;
import it.polimi.deib.se2.meteocal.business.entity.Calendar;
import it.polimi.deib.se2.meteocal.business.entity.Event;
import it.polimi.deib.se2.meteocal.business.entity.Location;
import it.polimi.deib.se2.meteocal.business.entity.User;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.joda.time.DateTime;

public class Utils {
    public static final String PATTERNEMAIL = "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
    
    public static Boolean validInviteesString(String invitees, String user) {
        CharSequence cs = user;
        
        if(invitees.contains(cs)){
            return false;
        }
        //regex reads as: match all valid email addresses followed by n others separated by a comma and eventually spaces
        return invitees.matches(PATTERNEMAIL+"(,( )*"+PATTERNEMAIL+")*");
    }
    
    public static Boolean timeConsistent(Calendar c, Date st, Date en) {
        DateTime startA = new DateTime(st);
        DateTime endA = new DateTime(en);
        
        //no start after end
        if(startA.compareTo(endA) > 0) {
            return false;
        }
        
        Collection<Event> list = c.getEventCollection();
        
        //time consistent with other events
        for(Event e : list) {
            DateTime startB = new DateTime(e.getStartDate());
            DateTime endB = new DateTime(e.getEndDate());
            if(!startB.equals(startA) || !endB.equals(endA)) {
                if(startA.compareTo(endB) <= 0 && endA.compareTo(startB) >= 0)
                    return false;
            }
        }
        return true;
    }
    
    public static String catchWeather(Event event) {
        int days = (int) getDateDiff(event.getStartDate(), TimeUnit.DAYS);
        String weatherExtracted = new String();
        if(days<0)
            weatherExtracted = "Day in the past";
        if(days>15)
            weatherExtracted = "Weather data not yet available";
        if(days>=0 && days<=15){
            Location eventLocation = event.getIdLocation();
            String weatherString = eventLocation.getWeather();
            weatherExtracted = extractWeather(weatherString, days);
        }
        
        return weatherExtracted;
    }
    public static int getDateDiff(Date startdate, TimeUnit timeUnit) {
        DateTime dt = new DateTime();
        int minutes = dt.getMinuteOfDay();
        Date now = dt.minusMinutes(minutes).toDate();
        long diffInMillies = startdate.getTime() - now.getTime();
        return (int)timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
    }
    
    public static String extractWeather(String weatherString, int days) {
        String[] weathers = weatherString.split(",");
        return weathers[days];
    }
    
    public static void prepareMail(String details, String receiver, String name){
        String[] splittedSubject = details.split(" ");
        StringBuilder subject = new StringBuilder();
        subject.append("MeteoCalApp - ");
        subject.append(splittedSubject[0]);
        subject.append(" ");
        subject.append(splittedSubject[1]);
        sendMail(receiver, details, subject.toString(), name);
    }
    
    public static List<String> autocomplete(Object manager, String query) {
        List<String> results = new ArrayList<String>();
        if(manager instanceof LocationManager) {
            List<Location> locations = ((LocationManager)manager).getLocations();
            
            for(Location l : locations) {
                if(l.getLocName().regionMatches(true, 0, query, 0, query.length())) {
                    results.add(query + l.getLocName().substring(query.length()));
                }
            }
        }
        return results;
    }
    
    public static String encryptPassword(String password) {
        String encPass = null;
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(password.getBytes("UTF-8"));
            BigInteger bigInt = new BigInteger(1, hash);
            encPass = bigInt.toString(16);
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
            Logger.getLogger(User.class.getName()).log(Level.SEVERE, null, ex);
        }
        return encPass;
    }
    
    private static void sendMail(String invitee, String details, String Subject, String name){
        
        final String username = "meteocalapp@gmail.com";
        final String password = "heroes2015";
        
        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.host", "smtp.gmail.com");
        props.put("mail.smtp.port", "587");
        
        Session session = Session.getInstance(props,
                new javax.mail.Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });
        
        try {
            
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress("meteocalapp@gmail.com"));
            message.setRecipients(Message.RecipientType.TO,
                    InternetAddress.parse(invitee));
            message.setSubject(Subject);
            message.setText("Dear " + name + ",\n\n" + details + "\n\n\n\n\n" + "MeteoCalApp Staff" + "\nwww.meteocalapp.com");
            
            Transport.send(message);
                        
        } catch (MessagingException e) {
            throw new RuntimeException(e);
        }
    }
    
}
